package com.whacos.modules.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.whacos.common.enums.Constant;
import com.whacos.common.enums.DelFlagEnum;
import com.whacos.common.shiro.ShiroUtils;
import com.whacos.common.utils.DateUtils;
import com.whacos.modules.system.dao.SysRoleDao;
import com.whacos.modules.system.dao.SysRoleMenuDao;
import com.whacos.modules.system.dao.SysUserRoleDao;
import com.whacos.modules.system.entity.SysRole;
import com.whacos.modules.system.entity.SysRoleMenu;
import com.whacos.modules.system.entity.SysUserRole;
import com.whacos.modules.system.service.SysRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;

/**
 * @author xiongdun
 * @description SysDeptServiceImpl
 * @since 2018/11/17 17:11
 */
@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleDao, SysRole> implements SysRoleService {

    @Autowired
    private SysRoleDao sysRoleDao;
    @Autowired
    private SysRoleMenuDao sysRoleMenuDao;
    @Autowired
    private SysUserRoleDao sysUserRoleDao;

    @Cacheable(cacheNames = Constant.DEFAULT_CACHE_NAME, key = "'sysRole'")
    @Override
    public List<SysRole> list() {
        return this.sysRoleDao.selectList(null);
    }

    @Cacheable(cacheNames = Constant.DEFAULT_CACHE_NAME, key = "'sysRole'")
    @Override
    public List<SysRole> list(Wrapper<SysRole> queryWrapper) {
        return super.list(queryWrapper);
    }

    @Override
    public List<SysRole> listByUserId(Long userId) {
        List<Long> rolesIds = this.sysUserRoleDao.listRoleId(userId);
        List<SysRole> sysRoleList = this.list();
        for (SysRole sysRole : sysRoleList) {
            sysRole.setSign("false");
            for (Long roleId : rolesIds) {
                if (Objects.equals(sysRole.getId(), roleId)) {
                    sysRole.setSign("true");
                    break;
                }
            }
        }
        return sysRoleList;
    }

    @CacheEvict(cacheNames = Constant.DEFAULT_CACHE_NAME, key = "'sysRole'")
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean removeById(Serializable id) {
        int result = sysRoleDao.deleteById(id);
        if (result > 0) {
            // 按roleId 删除用户角色关联表
            result = sysUserRoleDao.delete(new LambdaQueryWrapper<SysUserRole>()
                    .eq(SysUserRole::getRoleId, id));
        }
        if (result > 0) {
            // 按roleId 删除角色菜单关联表
            result = sysRoleMenuDao.delete(new LambdaQueryWrapper<SysRoleMenu>()
                    .eq(SysRoleMenu::getRoleId, id));
        }
        return result > 0;
    }

    @CacheEvict(cacheNames = Constant.DEFAULT_CACHE_NAME, key = "'sysRole'")
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean removeByIds(Collection<? extends Serializable> idList) {
        int result = sysRoleDao.deleteBatchIds(idList);
        if (result > 0) {
            result = sysUserRoleDao.delete(new LambdaQueryWrapper<SysUserRole>()
                    .in(SysUserRole::getUserId, idList));
        }
        if (result > 0) {
            result = sysRoleMenuDao.deleteBatchIds(idList);
        }
        return result > 0;
    }

    @CacheEvict(cacheNames = Constant.DEFAULT_CACHE_NAME, key = "'sysRole'")
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean updateById(SysRole entity) {
        entity.updatedData(ShiroUtils.getUserId());
        int result = sysRoleDao.updateById(entity);
        List<Long> menuIds = entity.getMenuIds();
        // 按roleId 删除角色菜单关联表
        sysRoleMenuDao.delete(new LambdaQueryWrapper<SysRoleMenu>()
                .eq(SysRoleMenu::getRoleId, entity.getId()));
        List<SysRoleMenu> sysRoleMenuList = new ArrayList<>();
        for (Long menuId : menuIds) {
            SysRoleMenu sysRoleMenu = new SysRoleMenu();
            sysRoleMenu.setRoleId(entity.getId());
            sysRoleMenu.setMenuId(menuId);
            sysRoleMenuList.add(sysRoleMenu);
        }
        if (sysRoleMenuList.size() > 0) {
            result = sysRoleMenuDao.batchInsert(sysRoleMenuList);
        }
        return result > 0;
    }

    @CacheEvict(cacheNames = Constant.DEFAULT_CACHE_NAME, key = "'sysRole'")
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean save(SysRole entity) {
        entity.createdData(ShiroUtils.getUserId());
        int result = sysRoleDao.insert(entity);
        List<Long> menuIds = entity.getMenuIds();
        Long roleId = entity.getId();
        List<SysRoleMenu> sysRoleMenuList = new ArrayList<>();
        for (Long menuId : menuIds) {
            SysRoleMenu sysRoleMenu = new SysRoleMenu();
            sysRoleMenu.setRoleId(roleId);
            sysRoleMenu.setMenuId(menuId);
            sysRoleMenuList.add(sysRoleMenu);
        }
        sysRoleMenuDao.delete(new LambdaQueryWrapper<SysRoleMenu>()
                .eq(SysRoleMenu::getRoleId, roleId));
        if (sysRoleMenuList.size() > 0) {
            result = sysRoleMenuDao.batchInsert(sysRoleMenuList);
        }
        return result > 0;
    }
}
